XSS 指的是恶意攻击者向 Web 页面里插入的恶意脚本代码,当用户浏览该页时,嵌入 Web 里面的脚本代码会被执行,从而达到恶意用户的特殊目的。
下面来看一个最简单的跨站脚本攻击范例,该代码使用 ASP.NET 接收一个传送的参数,并将其显示出来:
<%@ Page Language="C#"; ResponseEncoding="utf-8" ValidateRequest="False";
%><%string scriptString =
Request.QueryString[0];Response.Write(scriptString);
%>
这是一个最简单的动态网页,一般情况下没有问题,但是如果有恶意者使用下面的网址请求:
<a href="http://localhost/test.aspx?alert("hi!XSS" rel="nofollow">http://localhost/test.aspx?alert("hi!XSS</a> is here.");
由于没有对输入的请求进行验证就进行了输出,从而会执行客户端脚本代码。设想一下,如果某个地址是别人 " 骗你 " 单击一个链接发起的,并且客户端脚本代码是用来获取你的会话和 Cookie 的,那么你的这些信息将会被窃取,并被提交给攻击者的某一 Web 站点,从而可能被非法地恶意利用,这就是众所周知的 XSS ( Cross Site Scripting ,跨站脚本攻击)。
XSS 攻击主要是因不检查数据造成的,一般情况下,对请求的数据进行转换和过滤就可以有效防范 XSS 攻击。
数据的转换是可以在接受数据时,进入数据库时及输出数据时进行,因此,对于开发者,应该首先把精力放到对所有用户提交内容进行可靠的输入验证上,这些提交内容包括 URL 、查询关键字、 HTTP 报头、 POST 数据等。只接受在所规定长度范围内、采用适当格式及所希望的字符,过滤或者忽略其它内容。
如果 Web 应用程序必须支持用户提交 HTML 格式内容,那么应用的安全性将大大降低,因此除非必须这样做,否则一定不要提供此功能。但也有一些措施来保护 Web 应用程序,首先就是确认所接收的 HTML 内容被妥善地格式化,仅包含最小化的、安全的标签(绝对没有 script 元素),并且去掉任何对远程内容的引用(尤其是样式表和 JavaScript )。
下面是安全的、被允许使用的 HTML 标签,用户可以建立一个数组作为检核列表:
var allowedTags = [
'<font>',
'<span>',
'<p>',
'',
'<div>',
'<li>',
'<u>',
'<strike>',
'<strong>',
'<table>',
'<tr>',
'<td>',
'<tbody>',
'<hr>',
'<blockquote>',
'<sub>',
'<sup>',
'<ul>',
'<ol>',
'<img>',
'<b>',
'<em>',
'<h1>',
'<h2>',
'<h3>',
'<h4>',
'<h5>',
'<h6>',
];
事件属性也应该被绝对禁用,下面建立一个数组作为检核列表:
var disabledAttrs = [
'onabort',
'onactivate',
'onafterprint',
'onafterupdate',
'onbeforeactivate',
'onbeforecopy',
'onbeforecut',
'onbeforedeactivate',
'onbeforeeditfocus',
'onbeforepaste',
'onbeforeprint',
'onbeforeunload',
'onbeforeupdate',
'onblur',
'onbounce',
'oncellchange',
'onchange',
'onclick',
'oncontextmenu',
'oncontrolselect',
'oncopy',
'oncut',
'ondataavaible',
'ondatasetchanged',
'ondatasetcomplete',
'ondblclick',
'ondeactivate',
'ondrag',
'ondragdrop',
'ondragend',
'ondragenter',
'ondragleave',
'ondragover',
'ondragstart',
'ondrop',
'onerror',
'onerrorupdate',
'onfilterupdate',
'onfinish',
'onfocus',
'onfocusin',
'onfocusout',
'onhelp',
'onkeydown',
'onkeypress',
'onkeyup',
'onlayoutcomplete',
'onload',
'onlosecapture',
'onmousedown',
'onmouseenter',
'onmouseleave',
'onmousemove',
'onmoveout',
'onmouseover',
'onmouseup',
'onmousewheel',
'onmove',
'onmoveend',
'onmovestart',
'onpaste',
'onpropertychange',
'onreadystatechange',
'onreset',
'onresize',
'onresizeend',
'onresizestart',
'onrowexit',
'onrowsdelete',
'onrowsinserted',
'onscroll',
'onselect',
'onselectionchange',
'onselectstart',
'start',
'onstop',
'onsubmit',
'onunload',
];
此外,仅仅在客户端过滤是不够的,还要在服务器端过滤
一些应用程序服务器提供了实用功能,可以执行请求验证,这是一个请求过滤的方式,例如 ASP.NET 应用服务器就提供了这种功能
在 ASP.NET 网页中,。 使用 @Page 指令的 ValidateRequest 属性来设置是否开启请求验证,默认是开启的,即 ValidateRequest="True";
<%@ Page Language="C#"; ValidateRequest="True|False";%>
使用请求验证可以验证由客户。 提交的数据。 ASP.NET 内置有一个保存潜在危险值的列表,请求验证将用户输入的值与该列表进行对比,如果可以匹配,就会抛出一个异常提醒用户。验证的输入数据包括 QueryString 、 Form 和 Cookies
例如创建一个如下的网页:
<%@ P Language="C#"; ValidateRequest="True"; %>
使用下面的地址请求该网页:
<a href="http://lmssee.com/test.aspx?" rel="nofollow"
>http://localhost/test.aspx? /a>;</a
>
也可以在配置文件 Web.config 中设置整个应用程序的禁用请求验证,例如下面的配置:
<configuration>&l stem.web><pages
validateRequest="False"; /></system.web></configuration>
这项功能有助于减少对简单网页或 ASP.NET 应用程序进行跨站点脚本攻击和 SQL 注入式攻击的风险。但是,要注意,除了由 ASP.NET 执行的请求验证外,还应该在应用程序中显式地检查其使用的所有输入。请求验证功能无法捕捉所有攻击,特别是无法捕捉那些专门针对应用程序逻辑而策划的攻击
应该仔细地评估应用程序中所有形式的输入,并确保对它们进行了正确地验证和编码,或者确保应用程序在处理数据或将信息发送回客户端之前已退出。除此之外,别无它法